// -------------------------------------------------
// BlinKit - BlinKit Library
// -------------------------------------------------
//   File Name: qjs_page_popup_controller.cpp
// Description: Bindings for PagePopupController
//      Author: Ziming Li
//     Created: 2022-04-29
// -------------------------------------------------
// Copyright (C) 2022 MingYang Software Technology.
// -------------------------------------------------

#include "./qjs_bindings.h"

#include "blinkit/blink/public/platform/Platform.h"
#include "blinkit/blink/public/platform/WebThread.h"
#include "blinkit/blink/renderer/bindings/core/qjs/qjs.h"
#include "blinkit/blink/renderer/bindings/core/qjs/qjs_c_function_list_entries.h"
#include "blinkit/blink/renderer/core/dom/document.h"
#include "blinkit/blink/renderer/core/page/page_popup_controller.h"

namespace BlinKit {
namespace qjs {

static JSValue ClosePopup(JSContext *ctx, JSValueConst thisVal, int, JSValueConst *)
{
    PagePopupController *controller = ScriptWrappable::Cast<PagePopupController>(thisVal);
    controller->closePopup();
    return JS_UNDEFINED;
}

static JSValue SelectFontsFromOwnerDocument(JSContext *ctx, JSValueConst thisVal, int argc, JSValueConst *argv)
{
    PagePopupController *controller = ScriptWrappable::Cast<PagePopupController>(thisVal);

    Document *document = ScriptWrappable::Cast<Document>(argv[0]);
    controller->selectFontsFromOwnerDocument(document);
    return JS_UNDEFINED;
}

static JSValue SetValue(JSContext *ctx, JSValueConst thisVal, int argc, JSValueConst *argv)
{
    PagePopupController *controller = ScriptWrappable::Cast<PagePopupController>(thisVal);
    controller->setValue(ToWTFString(ctx, argv[0]));
    return JS_UNDEFINED;
}

static JSValue SetValueAndClosePopup(JSContext *ctx, JSValueConst thisVal, int argc, JSValueConst *argv)
{
    PagePopupController *controller = ScriptWrappable::Cast<PagePopupController>(thisVal);

    int32_t numValue;
    JS_ToInt32(ctx, &numValue, argv[0]);

    String strValue = ToWTFString(ctx, argv[1]);

    // PagePopupController::setValueAndClosePopup will destroy the JS runtime.
    // So it MUST run out of this JS context.
    Platform::current()->currentThread()->taskRunner()->postTask(BLINK_FROM_HERE, [controller, numValue, strValue] {
        controller->setValueAndClosePopup(numValue, strValue);
    });
    return JS_UNDEFINED;
}

static JSValue SetWindowRect(JSContext *ctx, JSValueConst thisVal, int argc, JSValueConst *argv)
{
    PagePopupController *controller = ScriptWrappable::Cast<PagePopupController>(thisVal);

    int32_t x, y, w, h;
    JS_ToInt32(ctx, &x, argv[0]);
    JS_ToInt32(ctx, &y, argv[1]);
    JS_ToInt32(ctx, &w, argv[2]);
    JS_ToInt32(ctx, &h, argv[3]);

    controller->setWindowRect(x, y, w, h);
    return JS_UNDEFINED;
}

void SetPagePopupControllerProperties(JSContext *ctx, JSValue obj)
{
    static const JSCFunctionListEntry Funcs[] = {
        CFunctionEntry("closePopup", 0, ClosePopup),
        CFunctionEntry("selectFontsFromOwnerDocument", 1, SelectFontsFromOwnerDocument),
        CFunctionEntry("setValue", 1, SetValue),
        CFunctionEntry("setValueAndClosePopup", 2, SetValueAndClosePopup),
        CFunctionEntry("setWindowRect", 4, SetWindowRect)
    };
    JS_SetPropertyFunctionList(ctx, obj, Funcs, std::size(Funcs));
}

} // namespace qjs
} // namespace BlinKit
